{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "- [manning-fpcpp-book / code-examples · GitLab](https://gitlab.com/manning-fpcpp-book/code-examples)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "此大纲将原书的章节逻辑重组为“概念导入 → 组合技法 → 副作用与并发 → 实践拓展”四大篇章，强调每一阶段的关键函数式工具和在 C++ 环境下的实现策略，便于读者逐步深入并对照实际开发需要。"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# 第一篇　函数式思想导入\n",
    "\n",
    "**第 1 章　函数式编程与 C++ 的相遇**\n",
    "\n",
    "- 函数式编程的核心理念：纯函数、不可变性、副作用管理\n",
    "- C++ 语言的命令式传统与函数式范式的兼容性\n",
    "- 引入迭代器、range（管道思想）、惰性求值的动机\n",
    "\n",
    "**第 2 章　函数对象与 Lambda 表达式**\n",
    "- 函数对象（Functors）、匿名函数、捕获语义\n",
    "- `auto`、`decltype`、`std::function` 在函数式构建中的角色\n",
    "- 值语义 vs. 引用语义：函数式风格需要注意的拷贝与持久性问题\n",
    "- **C++17+**：`constexpr` lambda、lambda 捕获 `*this`、模板 lambda、`auto` 非类型模板参数等增强\n",
    "\n",
    "**第 3 章　不可变性与值类型**\n",
    "- 不可变对象、持久化数据结构在 C++ 中的映射\n",
    "- 防止共享状态与数据竞争的设计策略\n",
    "- `const`、`constexpr`、浅/深不可变的界限\n",
    "- **C++20/23**：`constexpr` 容器操作、常量表达式中的函数式代码执行、`constinit` 辅助语义保证"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "vscode": {
     "languageId": "cpp"
    }
   },
   "outputs": [],
   "source": [
    "// range（管道思想）\n",
    "// 动机说明：以往需要写多次 std::transform、std::remove_if 或显式循环、临时 vector。range 管道把“数据流转”以组合式表达，既减少样板代码，也降低中间状态出错机会\n",
    "// 目标：将一组整数翻倍后，筛选出能被 3 整除的结果，并输出。使用 range 管道可避免中间容器、提升可读性\n",
    "\n",
    "#include <iostream>\n",
    "#include <ranges>\n",
    "#include <vector>\n",
    "\n",
    "int main() {\n",
    "    std::vector<int> data{1, 2, 3, 4, 5, 6};\n",
    "\n",
    "    // 通过管道把“变换”和“筛选”按阅读顺序串联，避免手写临时容器\n",
    "    auto pipeline = data\n",
    "        | std::views::transform([](int x) { return x * 2; })\n",
    "        | std::views::filter([](int x) { return x % 3 == 0; });\n",
    "\n",
    "    for (int value : pipeline) {\n",
    "        std::cout << value << ' ';  // 输出：6 12\n",
    "    }\n",
    "}"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "vscode": {
     "languageId": "cpp"
    }
   },
   "outputs": [],
   "source": [
    "// 惰性求值\n",
    "// 动机说明：即使 iota(0) 理论上产生无穷序列，只有在 take(3) 迭代时才触发前三个元素的计算，从而避免无意义的整体展开，天然适合惰性数据管道、按需加载、无限序列等场景\n",
    "// 目标：从无限整数序列中，仅取前 3 个平方数；惰性求值保证只在“拿到需要的元素”时才真正计算。\n",
    "\n",
    "#include <iostream>\n",
    "#include <ranges>\n",
    "\n",
    "int main() {\n",
    "    auto squares = std::views::iota(0)\n",
    "        | std::views::transform([](int x) {\n",
    "              std::cout << \"computing \" << x << '\\n';\n",
    "              return x * x;\n",
    "          });\n",
    "\n",
    "    for (int value : squares | std::views::take(3)) {\n",
    "        std::cout << \"value = \" << value << '\\n';\n",
    "    }\n",
    "}"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# 第二篇　组合式程序设计"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "**第 4 章　函数组合与高阶函数**\n",
    "- 函数组合器（composer）、部分应用（partial application）\n",
    "- 柯里化（currying）、占位符、`std::bind` 的局限与替代方案\n",
    "- 组合模式下的类型推导与模板技巧\n",
    "- **C++20**：`std::bind_front`、`std::function_ref`（提案）等更轻量的组合手段\n",
    "\n",
    "**第 5 章　惰性求值与流式管道**\n",
    "- 惰性序列、生成器、无限序列的安全处理\n",
    "- 迭代器、range-v3、pipes 的用法\n",
    "- 与 eager STL 算法的接口融合\n",
    "- **C++20/23**：`<ranges>` 标准化视图、`std::ranges::view`、`views::lazy_split/transform/filter`、range pipe 操作符\n",
    "\n",
    "**第 6 章　代数数据类型与泛型抽象**\n",
    "- `std::optional` / Maybe、`std::variant` / Either 等类型\n",
    "- 模拟 algebraic data types（代数数据类型）的模式\n",
    "- 利用模板实现 map、fold、filter 等抽象操作\n",
    "- **C++17+**：结构化绑定、`if constexpr`、`std::visit`（多态分发）、`std::any` 作为动态类型容器"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {
    "vscode": {
     "languageId": "cpp"
    }
   },
   "outputs": [],
   "source": [
    "// 函数组合（function composition） 是指把多个函数依次串联，使得前一个函数的输出成为后一个函数的输入。\n",
    "// 例如数学上的 h(x) = f(g(x))。在 C++ 中，我们可以创建一个通用的组合器，将多个可调用对象（callable）组合成一个高阶函数，提升代码的可读性与复用性。\n",
    "\n",
    "#include <iostream>\n",
    "#include <string>\n",
    "#include <utility>\n",
    "#include <algorithm>\n",
    "#include <cctype>\n",
    "\n",
    "// compose(f, g)(x) 等价于 f(g(x))\n",
    "template <typename F, typename G>\n",
    "auto compose(F&& f, G&& g) {\n",
    "    return [f = std::forward<F>(f), g = std::forward<G>(g)](auto&&... args) {\n",
    "        return f(g(std::forward<decltype(args)>(args)...));\n",
    "    };\n",
    "}"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {
    "vscode": {
     "languageId": "cpp"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "HELLO WORLD\n"
     ]
    }
   ],
   "source": [
    "{\n",
    "    auto trim = [](std::string s) {\n",
    "        s.erase(s.begin(), std::find_if(s.begin(), s.end(), [](unsigned char ch) {\n",
    "            return !std::isspace(ch);\n",
    "        }));\n",
    "        s.erase(std::find_if(s.rbegin(), s.rend(), [](unsigned char ch) {\n",
    "            return !std::isspace(ch);\n",
    "        }).base(), s.end());\n",
    "        return s;\n",
    "    };\n",
    "\n",
    "    auto to_upper = [](std::string s) {\n",
    "        std::transform(s.begin(), s.end(), s.begin(), [](unsigned char ch) {\n",
    "            return std::toupper(ch);\n",
    "        });\n",
    "        return s;\n",
    "    };\n",
    "\n",
    "    auto pretty = compose(to_upper, trim);\n",
    "\n",
    "    std::string raw = \"   hello world  \";\n",
    "    std::cout << pretty(raw) << '\\n'; // 输出：HELLO WORLD\n",
    "}"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {
    "vscode": {
     "languageId": "cpp"
    }
   },
   "outputs": [],
   "source": [
    "// 柯里化（Currying）\n",
    "// 柯里化把一个多参函数拆分成一系列“一次只接收一个参数”的函数，从而便于组合与重用。以下示例用模板实现了一个二元函数的简单柯里化器：\n",
    "// curry(add) 返回一个“只收第一个参数”的函数。\n",
    "// add5 即add(5, ·)的部分应用版本，后续可在组合链中复用\n",
    "\n",
    "#include <iostream>\n",
    "#include <utility>\n",
    "\n",
    "// 二元函数柯里化：curry(f)(x)(y) 等价于 f(x, y)\n",
    "template <typename F>\n",
    "auto curry(F&& f) {\n",
    "    return [f = std::forward<F>(f)](auto&& x) {\n",
    "        return [f, x = std::forward<decltype(x)>(x)](auto&& y) {\n",
    "            return f(x, std::forward<decltype(y)>(y));\n",
    "        };\n",
    "    };\n",
    "}"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {
    "vscode": {
     "languageId": "cpp"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "15\n"
     ]
    }
   ],
   "source": [
    "{\n",
    "    auto add = [](int a, int b) { return a + b; };\n",
    "\n",
    "    auto curried_add = curry(add); // 函数被拆成“链式调用”\n",
    "    auto add5 = curried_add(5);    // 对第一个参数部分应用\n",
    "    std::cout << add5(10) << '\\n'; // => 15\n",
    "}"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {
    "vscode": {
     "languageId": "cpp"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "15\n"
     ]
    }
   ],
   "source": [
    "{\n",
    "    auto add = [](int a, int b) { return a + b; };\n",
    "    std::cout << curry(add)(5)(10) << '\\n'; // => 15\n",
    "}"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "vscode": {
     "languageId": "cpp"
    }
   },
   "outputs": [],
   "source": [
    "// map：对每个元素应用函数，返回变换后的结果集合 https://godbolt.org/z/jev38bbbs\n",
    "\n",
    "#include <iostream>\n",
    "#include <vector>\n",
    "#include <type_traits>\n",
    "\n",
    "template <typename Range, typename F>\n",
    "auto fmap(const Range& range, F func) {\n",
    "    using In  = typename Range::value_type;\n",
    "    using Out = std::invoke_result_t<F&, In>;\n",
    "\n",
    "    std::vector<Out> result;\n",
    "    if constexpr (requires { range.size(); }) {\n",
    "        result.reserve(range.size());\n",
    "    }\n",
    "    for (const auto& elem : range) {\n",
    "        result.push_back(func(elem));\n",
    "    }\n",
    "    return result;\n",
    "}\n",
    "\n",
    "int main() {\n",
    "    std::vector<int> data{1, 2, 3, 4};\n",
    "\n",
    "    auto doubled = fmap(data, [](int x) { return x * 2; });\n",
    "\n",
    "    for (int v : doubled) {\n",
    "        std::cout << v << ' '; // 输出：2 4 6 8\n",
    "    }\n",
    "    std::cout << '\\n';\n",
    "}"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "vscode": {
     "languageId": "cpp"
    }
   },
   "outputs": [],
   "source": [
    "// fold：将容器元素按顺序折叠成单个值\n",
    "\n",
    "#include <iostream>\n",
    "#include <list>\n",
    "\n",
    "template <typename Range, typename Acc, typename F>\n",
    "Acc fold(const Range& range, Acc init, F func) {\n",
    "    for (const auto& elem : range) {\n",
    "        init = func(init, elem);\n",
    "    }\n",
    "    return init;\n",
    "}\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {
    "vscode": {
     "languageId": "cpp"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "sum = 10\n"
     ]
    }
   ],
   "source": [
    "{\n",
    "    std::list<int> data{1, 2, 3, 4};\n",
    "\n",
    "    int sum = fold(data, 0, [](int acc, int x) { return acc + x; });\n",
    "\n",
    "    std::cout << \"sum = \" << sum << '\\n'; // 输出：sum = 10\n",
    "}"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "vscode": {
     "languageId": "cpp"
    }
   },
   "outputs": [],
   "source": [
    "// filter：根据谓词保留满足条件的元素\n",
    "\n",
    "#include <iostream>\n",
    "#include <vector>\n",
    "\n",
    "template <typename Range, typename Pred>\n",
    "auto filter(const Range& range, Pred pred) {\n",
    "    using In = typename Range::value_type;\n",
    "\n",
    "    std::vector<In> result;\n",
    "    for (const auto& elem : range) {\n",
    "        if (pred(elem)) {\n",
    "            result.push_back(elem);\n",
    "        }\n",
    "    }\n",
    "    return result;\n",
    "}"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {
    "vscode": {
     "languageId": "cpp"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "2 4 6 \n"
     ]
    }
   ],
   "source": [
    "{\n",
    "    std::vector<int> data{1, 2, 3, 4, 5, 6};\n",
    "\n",
    "    auto evens = filter(data, [](int x) { return x % 2 == 0; });\n",
    "\n",
    "    for (int v : evens) {\n",
    "        std::cout << v << ' '; // 输出：2 4 6\n",
    "    }\n",
    "    std::cout << '\\n';\n",
    "}"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# 第三篇　纯度、效果与并发"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "**第 7 章　副作用管理与纯度维护**\n",
    "- 副作用分类：可观察、副作用隔离\n",
    "- I/O、状态包装进纯接口的技巧\n",
    "- “纯函数内核 + 副作用边界”架构模式\n",
    "- **C++20**：`co_await`、`co_yield`、协程对副作用隔离的启示（async pipeline）\n",
    "\n",
    "**第 8 章　表达式模板与 DSL**\n",
    "- 表达式模板（expression templates）基本原理\n",
    "- 构建函数式 DSL 的性能优化与链式操作\n",
    "- 惰性执行、内联展开对运行效率的影响\n",
    "- **C++20/23**：`constexpr` 算式化、Concepts 约束表达式模板、`std::mdspan` 等 DSL 组件的函数式封装\n",
    "\n",
    "**第 9 章　并发、异步与函数式思维**\n",
    "- 不可变性在多线程环境中的价值\n",
    "- 借助 `future`、`async`、`shared_future` 构建任务管线\n",
    "- 使用 `std::jthread`、`std::stop_token` 的可取消并行方案\n",
    "- 函数式技术减少锁竞争与共享状态\n",
    "- **C++20/23**：`std::latch`、`std::barrier`、原子 `wait/notify`、`std::osyncstream` 带来的安全并发管道；协程并发模型"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# 第四篇　实务案例与扩展\n",
    "\n",
    "**第 10 章　函数式工具箱与外部库**\n",
    "- Boost.Hana、Boost.Mp11、range-v3 等库的函数式能力\n",
    "- `std::tuple`、`std::apply`、`std::invoke` 的组合用法\n",
    "- 与元编程（TMP）交织的函数式范式\n",
    "- **C++17+**：Fold 表达式、`std::apply`、constexpr 元编程工具的成熟\n",
    "\n",
    "**第 11 章　项目实战与最佳实践**\n",
    "- 在既有命令式项目中导入函数式风格的策略\n",
    "- 将数据处理链重构为组合式 pipeline 的案例\n",
    "- 性能评估、可读性与可维护性的平衡\n",
    "- 与现代 C++ 特性整合的实践经验（如 ranges + 协程 + Concepts 组合）\n",
    "\n",
    "**第 12 章　C++17 以后函数式演进总结**\n",
    "- C++17：结构化绑定、`if constexpr`、`std::optional/variant/any`、`std::invoke` 等对函数式抽象的支持\n",
    "- C++20：Ranges、Concepts、协程、`constexpr` 增强、`std::bind_front`、`std::chrono` 扩展\n",
    "- C++23：`std::expected`, `std::views::transform` 增强、`std::generator`（提案）、`constexpr` 算法、`std::mdspan` 与函数式数值运算\n",
    "- 展望未来提案：Pattern Matching、`std::function_ref`、`std::flat_map`/`flat_set` 等对函数式代码模式的潜在影响\n",
    "- 函数式思维在现代 C++ 生态中的长远价值与演化趋势"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# 附录（可选）\n",
    "\n",
    "- 常用函数式工具速查（map/filter/reduce、组合器原型、惰性容器写法）\n",
    "- 函数式与命令式混合风格对照示例\n",
    "- C++17/20/23 函数式范式关键特性一览表\n",
    "- 推荐拓展阅读：Haskell/Scala/F#/JavaScript FP 思想与 C++ 的互通资料"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "C++17",
   "language": "C++17",
   "name": "xcpp17"
  },
  "language_info": {
   "codemirror_mode": "text/x-c++src",
   "file_extension": ".cpp",
   "mimetype": "text/x-c++src",
   "name": "c++",
   "version": "17"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
